#coding=utf-8

import docx
import docx.oxml.table as jud_table # 判断是否表格元素
import docx.oxml.text.paragraph as jud_para  # 判断是否自然段元素
import re
import string
import jieba # jieba分词库（中文分词库）
import chardet
import copy
import sys
reload(sys)
sys.setdefaultencoding("utf-8")

############################################################################################
# Get Information
# Get Table & Paragraph Information
# Paragraph : Regular Matching
# Table: Range Limit
############################################################################################

document = docx.Document('../年度报告/test6.docx')
paragraphs = document.paragraphs  # All Paragraphs of Document
tables = document.tables  # All Tables of Document
Para_start = []  # The Possible Para_Start
Para_end = []  # The Possible Para_End
title_number = []  # Use Title number to Def the Pos of the title

###############################################
# Regular Expressions Define
# 标题，关键字确定需要的表格和自然段的范围，减小搜索量
###############################################

pattern = re.compile(u'.董事.监事.高级管理人员和员工情况')
pattern1 = re.compile(u'.+董事')
pattern2 = re.compile(u'.+监事')
pattern3 = re.compile(u'.+高管')
pattern4 = re.compile(u'.+高级管理人员')

f_number = open('../词库/标题.txt', 'r')
try:
    dic_number = f_number.readlines()
finally:
    f_number.close()

font_size = 0  # the font_size of the Matching One
flag = False  # If find it become True
Want_para = []  # Result of Paragraph
Candidate = []
company = ''

for paragraph in paragraphs:
    tmp = paragraph.text.encode('utf-8')
    tmp = ''.join(tmp.split())
    if tmp != '':
        company = tmp
        break

###############################################
# Use A Broad & Unspecific Regular Expression
# 广义筛选，进行匹配，确定可能的范围
###############################################

for paragraph in paragraphs:
    tmp = paragraph.text.encode('utf-8')
    tmp = ''.join(tmp.split())
    match = pattern.search(unicode(tmp))
    if match:
        Candidate.append(paragraph)
        for index in xrange(0, len(dic_number)):
            number = ''.join(dic_number[index].split())
            pattern_number = re.compile(unicode(number))
            match = pattern_number.search(unicode(tmp))
            if match:
                string = ''.join(dic_number[index+1].split())
                title_number.append(string)
                break
        continue
    match = pattern1.search(unicode(tmp))
    if match:
        match = pattern2.search(unicode(tmp))
        if match:
            match1 = pattern3.search(unicode(tmp))
            match2 = pattern4.search(unicode(tmp))
            if match2 or match1:
                for index in xrange(0, len(dic_number)):
                    number = ''.join(dic_number[index].split())
                    pattern_number = re.compile(unicode(number))
                    match = pattern_number.search(unicode(tmp))
                    if match:
                        Candidate.append(paragraph)
                        string = ''.join(dic_number[index+1].split())
                        title_number.append(string)
                        break

flag = False

for index in xrange(0, len(Candidate)):
    for paragraph in paragraphs:
        if paragraph == Candidate[index]:
            flag = True
            Para_start.append(paragraph)
        elif flag:
            pattern_number = re.compile(unicode(title_number[index]))
            match = pattern_number.search(paragraph.text)
            if match:
                Para_end.append(paragraph)
                flag = False
                break
            else:
                Want_para.append(paragraph.text.encode('utf-8'))
########################################
# The test Code for Paragraph Information Get
########################################

# for i in Want_para:
#     print i

flag = False
Name_table = []
Want_table = []  # Result of Table

###############################################
# Use Paragraphs Start and End to Define the Tables Position
# 通过元素相对位置提取所需要的表格
###############################################

elements = document.element
for i in xrange(0, len(Para_start)):
    for element in elements.iterchildren():
        for children in element.iterchildren():
            if children < Para_start[i]._element:
                pass
            if children == Para_start[i]._element:
                flag = True
            elif children == Para_end[i]._element:
                flag = False
                break
            elif flag == True and isinstance(children, jud_table.CT_Tbl):  # Is Table Element?
                Name_table.append(children)

flag = False
for table in tables:
    if table._element == Name_table[0]:
        flag = True
        Want_table.append(table)
    elif table._element == Name_table[len(Name_table)-1]:
        Want_table.append(table)
        break
    elif flag == True:
        Want_table.append(table)

########################################
# The test Code for Table Information Get
########################################

# for i in Want_table:
#     for row in i.columns:
#         for unit in row.cells:
#             print unit.text.encode('utf-8')
#         print '++++++++++++++++++++++++'

############################################################################################
# Analyze Information
# Analyze the Information in Table & Paragraph, Then Set Them To a Complete Part
# Analyze Table : 屏蔽词列表，存储在以下目录中
# Analyze Paragraph : JieBa Lib of Python
############################################################################################

f_dic = open('../词库/排除.txt', 'r')
try:
    dic_resist = f_dic.readlines()
finally:
    f_dic.close()

flag = False
Want_name = []  # Store the table and unit of index
Want_head = {}  # Store the head infomation of table
Head_rows = {}

#########################################################
# Specific Version of the Recognize -------  Have Common Effect But Soft-coded
# Pattern of Store: [ Table Index, Row Index, Column Index]
#########################################################

pattern = re.compile(u'姓名')

k = 0
col_mark = row_mark = 0
while k < len(Want_table):
    row_size = len(Want_table[k].rows)
    yes = False
    if not flag:
        for i in xrange(row_mark, row_size):
            for j in xrange(0, len(Want_table[k].columns)):
                tmp = Want_table[k].rows[i].cells[j].text.encode('utf-8')
                tmp = ''.join(tmp.split())
                if tmp == '':
                    continue
                match = pattern.findall(unicode(tmp))
                if match:
                    col_mark = j
                    yes = True
                    row_mark = i
                    Head = []
                    for head in Want_table[k].rows[row_mark].cells:
                        strings = head.text.encode('utf-8')
                        strings = ''.join(strings.split())
                        Head.append(strings)
                    Want_head[k] = Head
                    Head_rows[k] = row_mark
                    Head = []
                    while row_mark < row_size:
                        tmp = Want_table[k].rows[row_mark].cells[col_mark].text.encode('utf-8')
                        tmp = ''.join(tmp.split())
                        if tmp == '':
                            row_mark += 1
                            continue
                        cannot = False
                        for resist in dic_resist:
                            resist = resist.replace('\n','')
                            pattern2 = re.compile(unicode(resist, 'utf-8'))
                            match = pattern2.findall(unicode(tmp, 'utf-8'))
                            if match:
                                row_mark += 1
                                cannot = True
                                break
                        if not cannot:
                            break
                        if row_mark == row_size and cannot:
                            yes = False
                    if yes:
                        flag = True
                    break
            if flag:
                break
            if not yes:
                row_mark = 0
                k += 1
                break
            if i == (row_size - 1):
                row_mark = 0
                k += 1
    if flag:
        for i in xrange(row_mark, row_size):
            tmp = Want_table[k].rows[i].cells[col_mark].text.encode('utf-8')
            tmp = ''.join(tmp.split())
            for resist in dic_resist:
                resist = resist.replace('\n', '')
                pattern1 = re.compile(unicode(resist, 'utf-8'))
                match = pattern1.findall(unicode(tmp, 'utf-8'))
                if match:
                    flag = False
                    row_mark = i
                    break
            if not flag:
                break
            else:
                point = [k, i, col_mark]
                Want_name.append(point)
        if flag:
            k += 1
            row_mark = 0
            continue

########################################
# Test Code of Name Set
########################################

# for i in Want_head:
#     for j in i:
#         print j
#     print '====================='
#
# for i in Want_name:
#     print Want_table[i[0]].rows[i[1]].cells[i[2]].text

name_used = []

f_new = open('../词库/职务.txt', 'r')
try:
    dic_work = f_new.readlines()
finally:
    f_new.close()

for work in dic_work:
    if work == '\n':
        dic_work.remove(work)

def Analyze(text, dic_work):
    for work in dic_work:
        work = ''.join(work.split())
        pattern2 = re.compile(unicode(work))
        match = pattern2.findall(unicode(text, 'utf-8'))
        if match:
            print text
    return

for i in Want_name:
    word = Want_table[i[0]].rows[i[1]].cells[i[2]].text.encode('utf-8')
    word = ''.join(word.split())
    if name_used.count(word) or word == '':
        continue
    name_used.append(word)
    pattern = re.compile(unicode(word, 'utf-8'))
    for paras in Want_para:
        match = pattern.search(unicode(paras,'utf-8'))
        if match:
            text = paras.replace(' ', '')
            Analyze(text, dic_work)

key_set = Want_head.keys()

#########################################################
# Solution:
# 使用链式正则匹配确定需要的表头，之后按列遍历
# Not Solved : 并行重复时间
#########################################################

pattern = re.compile(u'任期')
Time_table = []
key_set.sort()
for i in xrange(0, len(key_set)):
    flag1 = False
    flag2 = False
    f_date = False
    f_work = False
    name_set = []
    start_end = 0
    start = 0
    end = 0
    for head_cell in xrange(0, len(Want_head[key_set[i]])):
        match = pattern.findall(unicode(Want_head[key_set[i]][head_cell]))
        if match:
            pattern1 = re.compile(u'[起, 始]')
            pattern2 = re.compile(u'[止, 终]')
            match1 = pattern1.findall(unicode(Want_head[key_set[i]][head_cell]))
            match2 = pattern2.findall(unicode(Want_head[key_set[i]][head_cell]))
            if match1 and match2:
                start_end = head_cell
                flag1 = True
                f_date = True
            elif match1 and not match2 and not flag1:
                start = head_cell
                flag2 = True
            elif match2 and not match1 and not flag1 and flag2:
                end = head_cell
                f_date = True
        else:
            string = Want_head[key_set[i]][head_cell]
            pattern1 = re.compile(u'职务')
            match = pattern1.search(unicode(Want_head[key_set[i]][head_cell]))
            if match:
                position = head_cell
                f_work = True

    find = f_date and f_work
    if find:
        for k in Want_name:
            if i == len(key_set)-1 and k[0] >= key_set[i]:
                name_set.append(k)
            elif i < len(key_set)-1 and k[0] < key_set[i+1] and k[0] >= key_set[i]:
                name_set.append(k)
    lexicon = {'name': 'string', 'time': 'date', 'position': 'Null', 'Company': company}

#############################
# Date Formula
# 日期规范化正则表达式
#############################
    pattern1 = re.compile(ur"(\d\d\d\d)\s*[\./]\s*(\d\d?)\s*[\./]\s*(\d\d?)")
    pattern2 = re.compile(ur"(\d\d\d\d)\s*[\./]\s*(\d\d?)")
    pattern_date1 = re.compile(ur"(\d\d\d\d)年(\d\d?)月(\d\d?)日")
    pattern_date2 = re.compile(ur"(\d\d\d\d)年(\d\d?)月")

    if flag1 and find:
        flag = True
        time = ''
        if len(name_set):
            k = name_set[0]
            pre = tmp = Want_table[k[0]].rows[k[1]].cells[k[2]].text.encode('utf-8')
            lexicon['name'] = ''.join(tmp.split())
            tmp = Want_table[k[0]].rows[k[1]].cells[start_end].text.encode('utf-8')
            time += tmp
            match_pattern = pattern1.search(unicode(time))
            if match_pattern:
                time = re.sub(pattern1, ur"\1年\2月\3日", unicode(time))
            else:
                match_pattern = pattern2.search(unicode(time))
                if match_pattern:
                    time = re.sub(pattern2, ur"\1年\2月", unicode(time))
            time = time.encode('utf-8')
            tmp = Want_table[k[0]].rows[k[1]].cells[position].text.encode('utf-8')
            lexicon['position'] = ''.join(tmp.split())
            for index in xrange(1, len(name_set)):
                k = name_set[index]
                tmp = Want_table[k[0]].rows[k[1]].cells[k[2]].text.encode('utf-8')
                if tmp != pre:
                    flag = False
                    lexicon['time'] = time
                    Time_table.append(copy.deepcopy(lexicon))
                    time = ''
                    pre = tmp
                if not flag:
                    lexicon['name'] = ''.join(tmp.split())
                    tmp = Want_table[k[0]].rows[k[1]].cells[position].text.encode('utf-8')
                    lexicon['position'] = ''.join(tmp.split())
                tmp = Want_table[k[0]].rows[k[1]].cells[start_end].text.encode('utf-8')
                time += tmp
                match_pattern = pattern1.search(unicode(time))
                if match_pattern:
                    time = re.sub(pattern1, ur"\1年\2月\3日", unicode(time))
                else:
                    match_pattern = pattern2.search(unicode(time))
                    if match_pattern:
                        time = re.sub(pattern2, ur"\1年\2月", unicode(time))
                time = time.encode('utf-8')
                flag = True
                if index == len(name_set)-1 and flag:
                    lexicon['time'] = time
                    Time_table.append(copy.deepcopy(lexicon))
    elif flag2 and find:
        # Variable Definition
        flag = True
        start_time = ''
        end_time = ''

        # First Loop To set pre
        if len(name_set):
            k = name_set[0]
            pre = tmp = Want_table[k[0]].rows[k[1]].cells[k[2]].text.encode('utf-8')
            lexicon['name'] = ''.join(tmp.split())
            tmp = Want_table[k[0]].rows[k[1]].cells[position].text.encode('utf-8')
            lexicon['position'] = ''.join(tmp.split())
            tmp = Want_table[k[0]].rows[k[1]].cells[start].text.encode('utf-8')
            start_time += tmp
            match = pattern1.search(unicode(start_time))
            if match:
                start_time = re.sub(pattern1, ur'\1年\2月\3日', unicode(start_time))
            else:
                match = pattern2.search(unicode(start_time))
                if match:
                    start_time = re.sub(pattern2, ur'\1年\2月', unicode(start_time))
            start_time = start_time.encode('utf-8')
            tmp = Want_table[k[0]].rows[k[1]].cells[end].text.encode('utf-8')
            end_time += tmp
            match = pattern1.search(unicode(end_time))
            if match:
                end_time = re.sub(pattern1, ur'\1年\2月\3日', unicode(end_time))
            else:
                match = pattern2.search(unicode(end_time))
                if match:
                    end_time = re.sub(pattern2, ur'\1年\2月', unicode(end_time))
            end_time = end_time.encode('utf-8')

            for index in xrange(1, len(name_set)):
                k = name_set[index]
                tmp = Want_table[k[0]].rows[k[1]].cells[k[2]].text.encode('utf-8')
                if tmp != pre:
                    flag = False
                    lexicon['time'] = start_time + ' - ' + end_time
                    Time_table.append(copy.deepcopy(lexicon))
                    start_time = end_time = ''
                    pre = tmp
                if not flag:
                    lexicon['name'] = ''.join(tmp.split())
                    tmp = Want_table[k[0]].rows[k[1]].cells[position].text.encode('utf-8')
                    lexicon['position'] = ''.join(tmp.split())
                tmp = Want_table[k[0]].rows[k[1]].cells[start].text.encode('utf-8')
                start_time += tmp
                match = pattern1.search(unicode(start_time))
                if match:
                    start_time = re.sub(pattern1, ur'\1年\2月\3日', unicode(start_time))
                else:
                    match = pattern2.search(unicode(start_time))
                    if match:
                        start_time = re.sub(pattern2, ur'\1年\2月', unicode(start_time))
                start_time = start_time.encode('utf-8')

                tmp = Want_table[k[0]].rows[k[1]].cells[end].text.encode('utf-8')
                end_time += tmp
                match = pattern1.search(unicode(end_time))
                if match:
                    end_time = re.sub(pattern1, ur'\1年\2月\3日', unicode(end_time))
                else:
                    match = pattern2.search(unicode(end_time))
                    if match:
                        end_time = re.sub(pattern2, ur'\1年\2月', unicode(end_time))
                end_time = end_time.encode('utf-8')


                tmp = Want_table[k[0]].rows[k[1]].cells[position].text.encode('utf-8')
                tmp = ''.join(tmp.split())
                if tmp != lexicon['position'] and tmp != '':
                    lexicon['position'] += '、 '+tmp
                flag = True
                if index == (len(name_set)-1) and flag:
                    lexicon['time'] = start_time + ' - ' + end_time
                    Time_table.append(copy.deepcopy(lexicon))

#########################################################
# Test For Table Info Catch
#########################################################
for i in Time_table:
    print i['name'], i['time'].replace('\n', ''), i['position']

#########################################################
# The Next Steps:
# 1. 用结巴分词将自然段中已经解析出的片段进行分割（片段在Analyze函数中已经给出解析方法）
# 2. 将所有信息按照Want_name中的名字进行组合，输出最终结果，此过程中会涉及到去处重复的工作。
#########################################################